﻿// ***********************************************************************
// Assembly         : Tx.OCC
// Author           : tianteng
// Created          : 06-21-2019
//
// Last Modified By : tianteng
// Last Modified On : 06-21-2019
// ***********************************************************************
// <copyright file="OccImportExport.cs" company="北京腾雪科技有限责任公司">
//     Copyright © 北京腾雪科技有限责任公司 2022
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Collections.Generic;
using Occt;

namespace Tx.OCC
{
    /// <summary>
    /// Class OccImportExport.
    /// </summary>
    public static class OccImportExport
    {
        /// <summary>
        /// Loads the STP.
        /// </summary>
        /// <param name="stpFilePath">The STP file path.</param>
        /// <param name="outShapes">The out shapes.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool ReadStp(string stpFilePath, out TopoDS_Shape[] outShapes)
        {
            outShapes = null;
            var reader = new STEPControl_Reader();
            if (reader.ReadFile(stpFilePath) != IFSelect_ReturnStatus.IFSelect_RetDone)
                return false;

            bool failsonly = false;
            reader.PrintCheckLoad(failsonly, IFSelect_PrintCount.IFSelect_ItemsByEntity);
            var shapes = new List<TopoDS_Shape>();
            int aNbRoot = reader.NbRootsForTransfer;
            reader.PrintCheckTransfer(failsonly, IFSelect_PrintCount.IFSelect_ItemsByEntity);
            for (int aRootIter = 1; aRootIter <= aNbRoot; ++aRootIter)
            {
                reader.TransferRoot(aRootIter);
                int aNbShap = reader.NbShapes;
                if (aNbShap > 0)
                {
                    for (int aShapeIter = 1; aShapeIter <= aNbShap; ++aShapeIter)
                    {
                        shapes.Add(reader.Shape(aShapeIter));
                    }
                }
            }
            outShapes = shapes.ToArray();
            return true;
        }

        /// <summary>
        /// Loads the STP.
        /// </summary>
        /// <param name="stpFilePath">The STP file path.</param>
        /// <param name="labels">The labels.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool ReadStp(string stpFilePath, out TDF_LabelSequence labels)
        {
            labels = null;

            var reader = new STEPCAFControl_Reader();
            if (reader.ReadFile(stpFilePath) != IFSelect_ReturnStatus.IFSelect_RetDone)
                return false;
            // Set up the reader and the document
            XCAFApp_Application.Application.NewDocument("MDTV-XCAF", out TDocStd_Document document);
            // Transfer file to a document
            if (!reader.Transfer(document))
                return false;
            var mainLabel = document.Main;
            var rootNode = XCAFDoc_DocumentTool.ShapeTool(mainLabel);
            rootNode.GetFreeShapes(out labels);
            return true;
        }

        /// <summary>
        /// Writes the STP.
        /// </summary>
        /// <param name="stpFilePath">The STP file path.</param>
        /// <param name="shapes">The shapes.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool WriteStp(string stpFilePath, IEnumerable<TopoDS_Shape> shapes)
        {
            var aType = STEPControl_StepModelType.STEPControl_AsIs;
            var aWriter = new STEPControl_Writer();
            foreach (var shape in shapes)
            {
                if (aWriter.Transfer(shape, aType) != IFSelect_ReturnStatus.IFSelect_RetDone)
                {
                    return false;
                }
            }
            return aWriter.Write(stpFilePath) == IFSelect_ReturnStatus.IFSelect_RetDone;
        }

        /// <summary>
        /// Writes the STL.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shape">The shape.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool WriteSTL(string filePath, TopoDS_Shape shape)
        {
            var writer = new StlAPI_Writer();
            return writer.Write(shape, filePath);
        }
        /// <summary>
        /// Reads the STL.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shape">The shape.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool ReadSTL(string filePath, out TopoDS_Shape shape)
        {
            var writer = new StlAPI_Reader();
            return writer.Read(out shape, filePath);
        }

        /// <summary>
        /// Writes the brep.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shape">The shape.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool WriteBrep(string filePath, TopoDS_Shape shape)
        {
            return BRepTools.Write(shape, filePath);
        }

        /// <summary>
        /// Reads the brep.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shape">The shape.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool ReadBrep(string filePath, out TopoDS_Shape shape)
        {
            return BRepTools.Read(out shape, filePath, new BRep_Builder());
        }

        /// <summary>
        /// Reads the iges.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shape">The shape.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool ReadIges(string filePath, out TopoDS_Shape shape)
        {
            IGESControl_Reader aReader = new IGESControl_Reader();
            if (aReader.ReadFile(filePath) != IFSelect_ReturnStatus.IFSelect_RetDone)
            {
                shape = null;
                return false;
            }

            aReader.TransferRoots();
            shape = aReader.OneShape();
            return true;
        }
        /// <summary>
        /// Writes the iges.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shapes">The shapes.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool WriteIges(string filePath, IEnumerable<TopoDS_Shape> shapes)
        {
            IGESControl_Controller.Init();
            IGESControl_Writer aWriter = new IGESControl_Writer(Interface_Static.CVal("XSTEP.iges.unit"), Interface_Static.IVal("XSTEP.iges.writebrep.mode"));
            foreach (var shape in shapes)
            {
                if (shape.IsNull)
                {
                    return false;
                }

                aWriter.AddShape(shape);
            }
            aWriter.ComputeModel();
            return aWriter.Write(filePath);
        }

        /// <summary>
        /// Writes the VRML.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="shape">The shape.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool WriteVrml(string filePath, TopoDS_Shape shape)
        {
            VrmlAPI_Writer aWriter = new VrmlAPI_Writer();
            aWriter.Write(shape, filePath);
            return true;
        }
    }
}
